package jmine.tec.utils.annotation.visitor;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Collection;

/**
 * @author takeshi
 * @param <R> o tipo
 */
public interface ParameterAnnotationVisitor<R> {

    /**
     * Chamado para parametros de metodos
     * 
     * @param annotation a annotation
     * @param annotated a classe que declara
     * @param method o method
     * @param parameterIndex o indice do parametro que contem a annotation
     * @param parameterType o tipo de parametro
     * @param genericType o tipo generico
     * @return {@link Collection} de R
     */
    Collection<? extends R> onMethodParameterAnnotation(Annotation annotation, Class<?> annotated, Method method, int parameterIndex,
            Class<?> parameterType, Type genericType);

    /**
     * Chamado para parametros de metodos
     * 
     * @param annotation a annotation
     * @param annotated a classe que declara
     * @param method o method
     * @param parameterIndex o indice do parametro que contem a annotation
     * @param parameterType o tipo de parametro
     * @param genericType type o tipo generico
     * @return {@link Collection} de R
     */
    Collection<? extends R> onConstructorParameterAnnotation(Annotation annotation, Class<?> annotated, Constructor<?> method, int parameterIndex,
            Class<?> parameterType, Type genericType);

    /**
     * Deve devolver <code>true</code> se a anotacao do parametro do metodo deve ser lida por esta Annotation
     * 
     * @param annotation {@link Annotation}
     * @param declaring {@link Class}
     * @param method {@link Method}
     * @param parameterIndex int
     * @param paramterType {@link Class}
     * @param genericType {@link Type}
     * @return boolean
     */
    boolean acceptsMethodParameter(Annotation annotation, Class<?> declaring, Method method, int parameterIndex, Class<?> paramterType,
            Type genericType);

    /**
     * Deve devolver <code>true</code> se a anotacao do parametro do metodo deve ser lida por esta Annotation
     * 
     * @param annotation {@link Annotation}
     * @param declaring {@link Class}
     * @param ctor {@link Constructor}
     * @param parameterIndex int
     * @param paramterType {@link Class}
     * @param genericType {@link Type}
     * @return boolean
     */
    boolean acceptsConstructorParameter(Annotation annotation, Class<?> declaring, Constructor<?> ctor, int parameterIndex,
            Class<?> paramterType,
            Type genericType);

}
